/*
 * LevelEditor.java
 *
 * Created on Aug 10, 2011, 10:19:57 AM
 */
package sabokan;

import java.lang.reflect.Constructor;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import sabokan.game.Trace;
import sabokan.game.entities.Positionable;
import sabokan.game.entities.characters.Char;
import sabokan.game.entities.tiles.Tile;
import sabokan.game.enums.BoxEnum;
import sabokan.game.enums.CharacterEnum;
import sabokan.game.enums.ItemEnum;
import sabokan.game.enums.PlayerEnum;

/**
 * Container frame that renders LevelEditor
 * @author anaka
 */
public class LevelEditor extends javax.swing.JDialog {

    public LevelEditor(java.awt.Frame parent) {
        super(parent);
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainPanel = new javax.swing.JSplitPane();
        previewPanel = new javax.swing.JScrollPane();
        editorPanel = new sabokan.game.EditorPanel();
        controlsPanel = new javax.swing.JScrollPane();
        controlsPanelContainer = new javax.swing.JPanel();
        tileComboBox = new javax.swing.JComboBox();
        setTileButton = new javax.swing.JButton();
        setPlayerButton = new javax.swing.JButton();
        addItemButton = new javax.swing.JButton();
        addCharButton = new javax.swing.JButton();
        playerComboBox = new javax.swing.JComboBox();
        itemComboBox = new javax.swing.JComboBox();
        characterComboBox = new javax.swing.JComboBox();
        resetButton = new javax.swing.JButton();
        addBoxButton = new javax.swing.JButton();
        boxComboBox = new javax.swing.JComboBox();
        saveButton = new javax.swing.JButton();
        characterTextField = new javax.swing.JTextField();
        loadButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setName("Form"); // NOI18N

        mainPanel.setDividerLocation(500);
        mainPanel.setResizeWeight(0.5);
        mainPanel.setName("mainPanel"); // NOI18N

        previewPanel.setName("previewPanel"); // NOI18N

        editorPanel.setName("editorPanel"); // NOI18N
        editorPanel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                editorPanelMouseClicked(evt);
            }
        });

        javax.swing.GroupLayout editorPanelLayout = new javax.swing.GroupLayout(editorPanel);
        editorPanel.setLayout(editorPanelLayout);
        editorPanelLayout.setHorizontalGroup(
            editorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 540, Short.MAX_VALUE)
        );
        editorPanelLayout.setVerticalGroup(
            editorPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 749, Short.MAX_VALUE)
        );

        previewPanel.setViewportView(editorPanel);

        mainPanel.setLeftComponent(previewPanel);

        controlsPanel.setName("controlsPanel"); // NOI18N

        controlsPanelContainer.setName("controlsPanelContainer"); // NOI18N

        tileComboBox.setModel(new javax.swing.DefaultComboBoxModel(Tile.values()));
        tileComboBox.setName("tileComboBox"); // NOI18N

        setTileButton.setText("Set Tile"); // NOI18N
        setTileButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                setTileButtonActionPerformed(evt);
            }
        });

        setPlayerButton.setText("Set Player"); // NOI18N
        setPlayerButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                setPlayerButtonActionPerformed(evt);
            }
        });

        addItemButton.setText("Add Item"); // NOI18N
        addItemButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addItemButtonActionPerformed(evt);
            }
        });

        addCharButton.setText("Add Character"); // NOI18N
        addCharButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addCharButtonActionPerformed(evt);
            }
        });

        playerComboBox.setModel(new javax.swing.DefaultComboBoxModel(PlayerEnum.values()));
        playerComboBox.setName("playerComboBox"); // NOI18N

        itemComboBox.setModel(new javax.swing.DefaultComboBoxModel(ItemEnum.values()));
        itemComboBox.setName("itemComboBox"); // NOI18N

        characterComboBox.setModel(new javax.swing.DefaultComboBoxModel(CharacterEnum.values()));
        characterComboBox.setName("characterComboBox"); // NOI18N

        resetButton.setText("Reset"); // NOI18N
        resetButton.setName("resetButton"); // NOI18N
        resetButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                resetButtonActionPerformed(evt);
            }
        });

        addBoxButton.setText("Add Box"); // NOI18N
        addBoxButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addBoxButtonActionPerformed(evt);
            }
        });

        boxComboBox.setModel(new javax.swing.DefaultComboBoxModel(BoxEnum.values()));
        boxComboBox.setName("boxComboBox"); // NOI18N

        saveButton.setText("Save"); // NOI18N
        saveButton.setName("saveButton"); // NOI18N
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });

        characterTextField.setColumns(5);
        characterTextField.setText("Dialog Text Here"); // NOI18N
        characterTextField.setName("characterTextField"); // NOI18N

        loadButton.setText("Load"); // NOI18N
        loadButton.setName("loadButton"); // NOI18N
        loadButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                loadButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout controlsPanelContainerLayout = new javax.swing.GroupLayout(controlsPanelContainer);
        controlsPanelContainer.setLayout(controlsPanelContainerLayout);
        controlsPanelContainerLayout.setHorizontalGroup(
            controlsPanelContainerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(controlsPanelContainerLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(controlsPanelContainerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(controlsPanelContainerLayout.createSequentialGroup()
                        .addGroup(controlsPanelContainerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                            .addComponent(addBoxButton, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(setPlayerButton, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(addItemButton, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(addCharButton, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(setTileButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(controlsPanelContainerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(boxComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(tileComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(playerComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(itemComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(characterComboBox, 0, 140, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(characterTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(controlsPanelContainerLayout.createSequentialGroup()
                        .addComponent(resetButton, javax.swing.GroupLayout.PREFERRED_SIZE, 119, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(saveButton, javax.swing.GroupLayout.PREFERRED_SIZE, 119, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(loadButton, javax.swing.GroupLayout.PREFERRED_SIZE, 119, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        controlsPanelContainerLayout.setVerticalGroup(
            controlsPanelContainerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(controlsPanelContainerLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(controlsPanelContainerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(setTileButton)
                    .addComponent(tileComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(controlsPanelContainerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(setPlayerButton)
                    .addComponent(playerComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(controlsPanelContainerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(addItemButton)
                    .addComponent(itemComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(controlsPanelContainerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(addCharButton)
                    .addComponent(characterComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(characterTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(controlsPanelContainerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(addBoxButton)
                    .addComponent(boxComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(controlsPanelContainerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(resetButton, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(saveButton, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(loadButton, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(547, Short.MAX_VALUE))
        );

        controlsPanel.setViewportView(controlsPanelContainer);

        mainPanel.setRightComponent(controlsPanel);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1035, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(mainPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

private void resetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetButtonActionPerformed
    editorPanel.reset();
}//GEN-LAST:event_resetButtonActionPerformed

private void editorPanelMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_editorPanelMouseClicked
    editorPanel.setSelectedTile(evt);
}//GEN-LAST:event_editorPanelMouseClicked

private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
    JFileChooser chooser = new JFileChooser();
    if (JFileChooser.APPROVE_OPTION == chooser.showSaveDialog(this)) {
        editorPanel.saveLevel(chooser.getSelectedFile());
    }
}//GEN-LAST:event_saveButtonActionPerformed

private void addBoxButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addBoxButtonActionPerformed
    editorPanel.addBox(spawnEntity(((BoxEnum) boxComboBox.getSelectedItem()).getClazz()));
}//GEN-LAST:event_addBoxButtonActionPerformed

private void addCharButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addCharButtonActionPerformed
    Char tmpChar = spawnEntity(((CharacterEnum) characterComboBox.getSelectedItem()).getClazz());
    tmpChar.setDialogText(characterTextField.getText() != null ? characterTextField.getText() : "");
    editorPanel.addCharacter(tmpChar);
}//GEN-LAST:event_addCharButtonActionPerformed

private void addItemButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addItemButtonActionPerformed
    editorPanel.addItem(spawnEntity(((ItemEnum) itemComboBox.getSelectedItem()).getClazz()));
}//GEN-LAST:event_addItemButtonActionPerformed

private void setPlayerButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_setPlayerButtonActionPerformed
    editorPanel.setPlayer(spawnEntity(((PlayerEnum) playerComboBox.getSelectedItem()).getClazz()));
}//GEN-LAST:event_setPlayerButtonActionPerformed

private void setTileButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_setTileButtonActionPerformed
    editorPanel.setTile((Tile) tileComboBox.getSelectedItem());
}//GEN-LAST:event_setTileButtonActionPerformed

private void loadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadButtonActionPerformed
    JFileChooser chooser = new JFileChooser();
    if (JFileChooser.APPROVE_OPTION == chooser.showOpenDialog(this)) {
        editorPanel.loadLevel(chooser.getSelectedFile());
    }
}//GEN-LAST:event_loadButtonActionPerformed

    /**
     * Given a class of Positionable, returns an instance of it
     * @param <T>
     * @param clazz
     * @return 
     */
    private <T extends Positionable> T spawnEntity(Class<T> clazz) {
        T object = null;
        try {
            Integer x = Integer.valueOf(editorPanel.getSelected().x);
            Integer y = Integer.valueOf(editorPanel.getSelected().y);
            Constructor constr = clazz.getConstructor(new Class[]{int.class, int.class});
            object = (T) constr.newInstance(new Object[]{x, y});
        } catch (Exception e) {
            Trace.error("I failed to instantiate " + clazz.getName());
            JOptionPane.showMessageDialog(this, "I failed to instantiate " + clazz.getName(), "Error", JOptionPane.ERROR_MESSAGE);
        }
        return object;
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addBoxButton;
    private javax.swing.JButton addCharButton;
    private javax.swing.JButton addItemButton;
    private javax.swing.JComboBox boxComboBox;
    private javax.swing.JComboBox characterComboBox;
    private javax.swing.JTextField characterTextField;
    private javax.swing.JScrollPane controlsPanel;
    private javax.swing.JPanel controlsPanelContainer;
    private sabokan.game.EditorPanel editorPanel;
    private javax.swing.JComboBox itemComboBox;
    private javax.swing.JButton loadButton;
    private javax.swing.JSplitPane mainPanel;
    private javax.swing.JComboBox playerComboBox;
    private javax.swing.JScrollPane previewPanel;
    private javax.swing.JButton resetButton;
    private javax.swing.JButton saveButton;
    private javax.swing.JButton setPlayerButton;
    private javax.swing.JButton setTileButton;
    private javax.swing.JComboBox tileComboBox;
    // End of variables declaration//GEN-END:variables
}
